#include "detection.hpp"

void test_print()
{
    printf("hello world!");
}


/*
    input:
        image:CV_8UC3
    output:
        dst:CV_8UC3
    function:
        drawRec on src target area,copy target area to dst
*/

/*
 * 寻找目标区域，得出ROI
 * input:
 *  src:目标图像
 *  dst:一个和src一样大的空图
 * output:
 *  ret：后面在dst的rec区域寻找矩形
*/
//Rect far_target_detecion(Mat src)
//{
//    if ( !src.data )
//    {
//        printf("No image data \n");
//        //return;
//    }
//    Mat image;
//    cvtColor( src, image, CV_BGR2GRAY );
//    Mat binImg; //二进制图像
//    //获得进行开运算的核kenel
//    Mat element = getStructuringElement(MORPH_RECT, Size(3,3));
//    threshold(image, binImg, 0, 255, CV_THRESH_OTSU);
//    //adaptiveThreshold(image, binImg, 200, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 3, 5);
//    //MORPH_OPEN进行开运算，消除小物体
//    morphologyEx(binImg, binImg, MORPH_OPEN, element);
////    namedWindow("binImg");
////    imshow("binImg", binImg);
////    waitKey(10);
//    namedWindow("src",0);
//     imshow("src",src);

//    //用于保存所有轮廓信息
//    vector< vector< Point> > contours;
//    vector<Vec4i> hierarchy;
//    findContours(binImg, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
//    int idx_num = contours.size();
//    int idx_left = idx_num; //剩余的轮廓数
//    //cout<<"the total contours:"<<idx_num<<endl;

//    //遍历每个轮廓
//    for(int i=0; i<idx_num; i++)
//    {
//        /*获得轮廓的boundingrect
//         * 这里的rect用来:
//         * 1.画图
//         * 2.返回感兴趣区域
//         * 3.判断矩形的大小
//         */
//        Rect rect = boundingRect(contours[i]);
//        int w = rect.width;
//        int h = rect.height;
//        float shape_ratio = contourArea(contours[i], false )*4*CV_PI/contours[i].size()/contours[i].size();
////        origin.x = x;
////        origin.y = y+15;

///*
//        if(i == 190)
//        {
//            printf("shape ratio:%f\n",contourArea(contours[i], false )*4*PI/contours[i].size()/contours[i].size());
//            printf("contourArea:%f\n",contourArea(contours[i], false ));
//            printf("contourSize:%d\n",contours[i].size());
//            rectangle(src, rect, Scalar(0,0,255));
//            sprintf(contours_tag,"tag_%d",i);
//            putText(src, contours_tag, origin, 1, FONT_HERSHEY_PLAIN, Scalar(0,0,255));
//            Scalar color( rand()&255, rand()&255, rand()&255 );
//            drawContours( src, contours, i, color, 1, 8);
//        }
//*/

//        //此时的条件：
////        1.轮廓的面积
////        2.长宽比
////        3.面积/周长平方比
//        //？？？w,h均是boundingrect的长和宽
//        if(contours[i].size() < 100 ||w<0.2*h||w>5*h)
//        {
//            idx_left--;
//            continue;
//        }

//        else if(shape_ratio < 0.45) //change 0.6 to 0.4
//        {
//            idx_left--;
//            continue;
//        }

////        printf("shape ratio:%f",contourArea(contours[i], false )*4*PI/contours[i].size()/contours[i].size());
////        rectangle(src, rect, Scalar(0,0,255));
////        sprintf(contours_tag,"tag_%d",i);
////        putText(src, contours_tag, origin, 1, FONT_HERSHEY_PLAIN, Scalar(0,0,255));
////        Scalar color( rand()&255, rand()&255, rand()&255 );
////        drawContours( src, contours, i, color, 1, 8);

//        //看完矩形boundingrect是否符合后，看子轮廓是否符合
//        /*
//         * 子轮廓的形态学条件:
//         * 1.shape_ratio>0.65
//         * 2.矩形周长的0.15倍 < 子轮廓周长 < 矩形周长的0.5倍
//         */
//        //count child contours num
//        if(hierarchy[i][2] != -1)
//        {
//            int child_ID=hierarchy[i][2]; //the first child of i
//            int circle_child=0;
//            int biggest_child_perimeter=0; //a bug: ii but not i
//            int second_child_perimeter=0;
//            float child_shape_ratio;
////            cout<<contours[child_ID].size()<<endl;
//            //判断第一个child
//            child_shape_ratio = contourArea(contours[child_ID], false )*4*CV_PI/contours[child_ID].size()/contours[child_ID].size();
//            if(child_shape_ratio>0.65 && contours[child_ID].size()>0.15*contours[i].size() && contours[child_ID].size()<0.5*contours[i].size())    //0405 shape ratio changed from 0.8 to 0.7
//            {
//                circle_child++;
////                biggest_child_perimeter = contours[child_ID].size();
//            }
//            while(hierarchy[child_ID][0] != -1) //find all child
//            {
//                child_ID = hierarchy[child_ID][0];
//                if(child_shape_ratio>0.65 && contours[child_ID].size()>0.15*contours[i].size() && contours[child_ID].size()<0.5*contours[i].size())    //0405 shape ratio changed from 0.8 to 0.7
//                {
//                    circle_child++;  //if the first child is cicle_child,it will not be caculated,bug ???
//                }

//                if(contours[child_ID].size()<=biggest_child_perimeter) // <= but not <
//                {
//                    if(contours[child_ID].size() >second_child_perimeter)
//                    second_child_perimeter = contours[child_ID].size();
//                }
//                else
//                {
//                    second_child_perimeter = biggest_child_perimeter; //a fixed bug:save the biggest value to second
//                    biggest_child_perimeter = contours[child_ID].size();
//                }
//            }
//            printf("%d\n",circle_child);
//            //若有两个圆形子轮廓，且符合形态
//            /*
//             * 1.声明和原图大的mask
//             * 2.在mask上画出这个矩形轮廓（填充）
//             * 3.copy mask to dst（dst是和原图一样大的空图），即dst成了仅有这一块rectbouding的图
//             * 4.在原图中画出矩形的boundingrect
//             * 5.随机挑选一个颜色，在原图中标出这个矩形轮廓
//             */
//            if(circle_child == 2 && biggest_child_perimeter <1.5*second_child_perimeter)
//            {
//                rectangle(src,rect,Scalar(255,0,0));
////                namedWindow("src",0);
////                imshow("src",src);
////                waitKey(10);
////                drawContours(src, contours, i, Scalar(255,255,255), CV_FILLED, 8);
//                //在src中画出rect，在开头就辨识出的矩形
////                rectangle(src, rect, Scalar(255,0,0),2);
////                sprintf(contours_tag,"tag_%d",i);
//                //putText(src, contours_tag, origin, 1, FONT_HERSHEY_PLAIN, Scalar(0,0,255));
////                Scalar color( rand()&255, rand()&255, rand()&255 );
////                drawContours( src, contours, i, color, 1, 8);
//                return rect;
//            }
//            else
//            {
//                idx_left--;
//                continue;
//            }
//        }
//        else
//        {
//            idx_left--;
//            continue;
//        }
//    }
//    //cout<<"the total contours:"<<idx_num<<"\t the left contours:"<<idx_left<<endl;
//    Rect rec_default(0, 0, src.cols, src.rows);
//    return rec_default;
//}

Rect far_target_detecion(Mat src, Mat dst )
{
    if ( !src.data )
    {
        printf("No image data \n");
        //return;
    }
    Mat image;
    cvtColor( src, image, CV_BGR2GRAY );
    Mat binImg;
    //获得进行开运算的核kenel
    Mat element = getStructuringElement(MORPH_RECT, Size(3,3));

    threshold(image, binImg, 0, 255, CV_THRESH_OTSU);
    //adaptiveThreshold(image, binImg, 200, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 3, 5);

    //MORPH_OPEN进行开运算，消除小物体
    morphologyEx(binImg, binImg, MORPH_OPEN, element);
//    imshow("step1:binImg", binImg);

    //用于保存所有轮廓信息
    vector< vector< Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(binImg, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
    int idx_num = contours.size();;
    int idx_left = idx_num; //剩余的轮廓数
    //cout<<"the total contours:"<<idx_num<<endl;

    //遍历每个轮廓
    for(int i=0; i<idx_num; i++)
    {
        //获得轮廓的boundingrect
        Rect rect = boundingRect(contours[i]);
        int w = rect.width;
        int h = rect.height;
        float contour_area = contourArea(contours[i], false );
        float shape_ratio = contour_area*4*CV_PI/contours[i].size()/contours[i].size();

/*
        if(i == 190)
        {
            printf("shape ratio:%f\n",contourArea(contours[i], false )*4*PI/contours[i].size()/contours[i].size());
            printf("contourArea:%f\n",contourArea(contours[i], false ));
            printf("contourSize:%d\n",contours[i].size());
            rectangle(src, rect, Scalar(0,0,255));
            sprintf(contours_tag,"tag_%d",i);
            putText(src, contours_tag, origin, 1, FONT_HERSHEY_PLAIN, Scalar(0,0,255));
            Scalar color( rand()&255, rand()&255, rand()&255 );
            drawContours( src, contours, i, color, 1, 8);
        }
*/

        //此时的条件：
//        1.轮廓的面积
//        2.长宽比
//        3.面积/周长平方比
        //？？？w,h均是boundingrect的长和宽
        if(contours[i].size() < 100 ||w<0.2*h||w>5*h)
        {
            idx_left--;
            continue;
        }

        else if(shape_ratio < 0.45) //change 0.6 to 0.4
        {
            idx_left--;
            continue;
        }

//        printf("shape ratio:%f",contourArea(contours[i], false )*4*PI/contours[i].size()/contours[i].size());
//        rectangle(src, rect, Scalar(0,0,255));
//        sprintf(contours_tag,"tag_%d",i);
//        putText(src, contours_tag, origin, 1, FONT_HERSHEY_PLAIN, Scalar(0,0,255));
//        Scalar color( rand()&255, rand()&255, rand()&255 );
//        drawContours( src, contours, i, color, 1, 8);

        //看完矩形boundingrect是否符合后，看子轮廓是否符合
        //count child contours num
        if(hierarchy[i][2] != -1)
        {
            int ii=hierarchy[i][2]; //ii is the first child of i
            int small_child=0;
            int cicle_child=0;
            int child_num=0;
            int biggest_child_area=contours[ii].size(); //a bug: ii but not i
            int second_child_area=0;
            child_num++;

            //if child_num >1
            while(hierarchy[ii][0] != -1) //find all child
            {
                float child_shape_ratio = contourArea(contours[ii], false )*4*CV_PI/contours[ii].size()/contours[ii].size();
                if(contours[ii].size()<contours[i].size()*0.15)
                {
                    small_child++;  //not used
                }
                if(child_shape_ratio>0.65 && contours[ii].size()>0.15*contours[i].size() && contours[ii].size()<0.5*contours[i].size())    //0405 shape ratio changed from 0.8 to 0.7
                {
                    cicle_child++;  //if the first child is cicle_child,it will not be caculated,bug
                }
                child_num++;

                ii = hierarchy[ii][0];
                if(contours[ii].size()<=biggest_child_area) // <= but not <
                {
                    if(contours[ii].size() >second_child_area)
                    second_child_area = contours[ii].size();
                }
                else
                {
                    second_child_area = biggest_child_area; //a fixed bug:save the biggest value to second
                    biggest_child_area = contours[ii].size();
                }
            }
            // now ii point to the last child(if only one child then ii point to the first child)
            float child_shape_ratio = contourArea(contours[ii], false )*4*CV_PI/contours[ii].size()/contours[ii].size();
            if(child_shape_ratio>0.65 && contours[ii].size()>0.15*contours[i].size() && contours[ii].size()<0.5*contours[i].size())    //0405 shape ratio changed from 0.8 to 0.6
            {
                cicle_child++;  //if the first child is cicle_child,it will not be caculated,bug
            }

            //若没有子轮廓，跳过
            //if(child_num ==0 || child_num >10)
            if(child_num ==0)
            {
                idx_left--;
                continue;
            }
            //若有圆形子轮廓，且符合形态
            /*
             * 1.声明和原图大的mask
             * 2.在mask上画出这个矩形轮廓（填充）
             * 3.copy mask to dst（dst是和原图一样大的空图），即dst成了仅有这一块rectbouding的图
             * 4.在原图中画出矩形的boundingrect
             * 5.随机挑选一个颜色，在原图中标出这个矩形轮廓
             */
            else if(cicle_child>=1 && biggest_child_area <1.5*second_child_area)
            {
//                printf("cicle_child:%d\n",cicle_child);
//                Mat mask = Mat::zeros(image.size(), CV_8UC1);
//                drawContours( mask, contours, i, Scalar(255,255,255), CV_FILLED, 8);
//                src.copyTo(dst, mask);

                //在src中画出rect，在开头就辨识出的矩形
//                rectangle(src, rect, Scalar(0,0,255),2);
//                sprintf(contours_tag,"tag_%d",i);
                //putText(src, contours_tag, origin, 1, FONT_HERSHEY_PLAIN, Scalar(0,0,255));
//                Scalar color( rand()&255, rand()&255, rand()&255 );
//                drawContours( src, contours, i, color, 1, 8);

                return rect;
            }
            else
            {
                idx_left--;
                continue;
            }
        }
        else
        {
            idx_left--;
            continue;
        }
    }
    //cout<<"the total contours:"<<idx_num<<"\t the left contours:"<<idx_left<<endl;
    Rect rec_default(0, 0, src.cols, src.rows);
    return rec_default;
}
